C++ 中的函数指针


2022 年 10 月 8 日, Learn eTutorial
2003

什么是函数指针?

  • 函数指针是一种变量,主要用于存储函数的地址,稍后可以使用该函数指针调用该函数。
  • 我们已经在 C++ 函数教程中学习了如何向函数传递参数。由于传递的是实际值,因此这种方法被称为按值传递。
  • 我们都知道,指针用于指向变量。同样,用于指向函数的指针似乎就是函数指针。
  • 在这种方法中,参数的实际值根本不被传递,但是,还有另一种向函数传递参数的方法。作为替代,传递的是值的引用。

语法

声明函数指针的语法


int *funcPtr(int, int)
 
  • 函数声明使用上述语法进行。尽管函数比变量更复杂,但 C++ 中的函数指针是类型安全的,因此函数指针既有返回类型也有参数列表。
  • 在上述语法中,首先提供返回类型,然后是括号中包含的指针名称(即 FuncPtr),其前面带有 (*) 指针符号。
  • 然后我们提供了参数列表 (int, int)。上述语法中的函数指针可以指向任何接受两个整数参数并返回整数类型值的函数。

函数地址是什么意思?

What do you mean by the address of a function

计算机只能理解二进制形式,这是一种低级语言。由于我们编写的 C++ 代码总是用高级语言编写的,因此编译器用于将其翻译成二进制代码。编译器是一个主要将源代码转换为可执行代码的程序。此可执行文件存储在内存 (RAM) 中。main() 方法是 CPU 开始执行的地方。它读取当前在 RAM 中而不是在原始文件中的副本。

所有机器代码指令和函数都是数据。此数据由许多字节组成,每个字节都有一个 RAM 地址。函数指针中的 RAM 地址位于函数的初始指令处。

C++ 中函数的地址

我们可以快速获取函数的地址。为此,我们不必调用函数,我们只需指定其名称。

让我们通过一个简单的例子来理解这个概念


#include <iostream>
using namespace std;
int main() {

cout << "Address of a main() function is: " << &main << endl;
return 0;
}

输出

Address of a main() function is: 1

程序的运行

  • 上面的程序显示了 main() 函数的地址。
  • 我们只提到了函数的名称及其地址,以便打印 main() 函数的地址;没有括号或参数。
  • 因此,函数的地址仅由函数名称表示,不带任何括号或参数。
  • 我们可以使用替代方法 &main 来打印函数的地址。

我们如何调用函数?

我们可以通过提供函数指针的名称来使用函数指针调用函数。

通过函数指针调用函数所使用的语法将与我们直接或正常调用函数时相同。

示例:使用函数指针编写一个 C++ 程序来打印总和。
 


#include <iostream>
using namespace std;
int sum(int a, int b) {

    return a + b;
}
int main() {

    int(*funcPtr)(int,int); // function pointer is  declared
    funcPtr = sum; // funcPtr is pointing towards the sum function
    int sum = funcPtr (2, 4);
    cout << "Then the value of sum is: " << sum << endl;
    return 0;
}

输出


Then the value of sum is: 6

函数指针在上述程序中被声明为 int (*funcptr)(int,int),然后将 add() 函数的地址存储在 funcptr 中。这表明 add() 函数的地址在 funcptr 中。

现在,我们可以使用 funcptr 来调用 add() 函数。add() 函数由表达式 funcptr(2,4) 调用,输出保存在 sum 变量中。

我们如何使用函数指针打印名称?

为此,让我们编写一个 C++ 程序来使用函数指针打印名称。

我们使用 static_cast 运算符来输出 void 指针的内容。它将指针的数据类型从其原始的 void* 类型更改为它所存储的地址的类型。


#include <iostream>  
using namespace std;  
void printname(char *name)  
{  
    std::cout << "Name is :" <<name<< std::endl;  
}  
  
int main()  
{  
    char s[20];  //the array declaration  
    void (*ptr)(char*);  // function pointer declaration  
    ptr=printname;  // storing the address of printname in ptr.  
    std::cout << "Please enter the name of the person: " << std::endl;  
    cin>>s;  
    cout<<s;  
    ptr(s);  // calling the printname() function  
   return 0;  
}

输出

Please enter the name of the person: 
Lali
Name is Lali

函数 printname(),其参数为 char 指针,在上述程序中定义。函数指针声明为 void (*ptr)(char*)。要将 printname() 函数的地址赋给 ptr,请使用语法 ptr=printname。现在,我们可以使用 ptr 语句 (s) 调用 printname() 函数。

如何在 C++ 中将函数指针作为参数传递?

如这里所示,我们可以将函数指针作为参数传递给我们的程序。


#include <iostream>  
using namespace std;  
void function1()  
{  
    cout<<" The function1 is called";  
}  
void function2(void (*funcptr)())  
{  
    funcptr();  
}  
int main()  
{  
  function2(function1);  
  return 0;  
}

输出

The function1 is called

在前面的程序中,我们给函数2() 函数传递了一个函数指针作为参数。main() 方法给 func2() 函数传递了 function1() 的地址。这样,function2() 函数间接调用了 function1() 函数。

您应该了解以下有关函数指针的事实

  • 函数指针不像其他指针那样指向数据;相反,它指向程序代码。函数指针通常用于存储可执行代码的开头。
  • 与普通指针不同,我们不使用函数指针来分配或释放内存。
  • 也可以使用函数的名称来确定该函数的地址。
  • 适用于普通指针的相同规则也适用于函数指针数组。
  • 函数指针可以用来代替 switch case。
  • 与数据指针可以作为参数传递并从函数返回类似,函数指针也可以这样做。

本文涵盖了函数指针。我们已经看到了函数指针的价值、它们的使用位置以及它们如何使我们的程序更容易设计和维护。